package com.z8888q.zerodays.datepicker;

import java.text.DateFormatSymbols;
import java.util.Calendar;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;

import com.z8888q.zerodays.R;

public class DateWheelPicker extends RelativeLayout {
	public DateWheelPicker(Context context) {
		this(context, null);
		// TODO Auto-generated constructor stub
	}

	public DateWheelPicker(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
		// TODO Auto-generated constructor stub
	}

	public DateWheelPicker(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		inflater.inflate(R.layout.date_layout, this, true);
		init();
	}

	private static final int DEFAULT_START_YEAR = 1900;
	private static final int DEFAULT_END_YEAR = 2100;
	// Time changed flag
	private boolean timeChanged = false;

	//
	private boolean timeScrolled = false;

	private int mDay = 0;
	private int mMonth = 0;
	private int mYear = 0;
	private WheelView mDayPicker;
	private WheelView mYearPicker;
	private WheelView mMonthPicker;

	Button button_ok;
	Button button_cancel;

	/**
	 * How we notify users the date has changed.
	 */
	private OnDateWheelPickerDateChangedListener mOnDateWheelPickerDateChangedListener;

	/**
	 * The callback used to indicate the user changes the date.
	 */
	public interface OnDateWheelPickerDateChangedListener {

		/**
		 * @param view
		 *            The view associated with this listener.
		 * @param year
		 *            The year that was set.
		 * @param monthOfYear
		 *            The month that was set (0-11) for compatibility with
		 *            {@link java.util.Calendar}.
		 * @param dayOfMonth
		 *            The day of the month that was set.
		 */
		void onDateWheelPickerDateChanged(int year, int monthOfYear, int dayOfMonth);
	}

	/**
	 * How we notify users the date has setted.
	 */
	private OnDateWheelPickerDateSettedListener mOnDateWheelPickerDateSettedListener;

	/**
	 * The callback used to indicate the user set the date.
	 */
	public interface OnDateWheelPickerDateSettedListener {

		void onDateWheelPickerDateSetted(int year, int monthOfYear, int dayOfMonth);
	}

	private void init() {
		// /////////////////////////////////////
		mDayPicker = (WheelView) findViewById(R.id.hour);
		mDayPicker.setCyclic(true);
		mDayPicker.addChangingListener(new OnWheelChangedListener() {
			@Override
			public void onChanged(WheelView wheel, int oldValue, int newValue) {
				Log.e("Day:", "" + newValue);
				mDay = newValue;
				if (mOnDateWheelPickerDateChangedListener != null) {
					mOnDateWheelPickerDateChangedListener.onDateWheelPickerDateChanged(mYear, mMonth, mDay + 1);
				}
			}
		});

		// ////////////////////////////////////////
		mMonthPicker = (WheelView) findViewById(R.id.mins);
		mMonthPicker.setCyclic(true);
		DateFormatSymbols dfs = new DateFormatSymbols();// DateFormatSymbols();
		String[] months = dfs.getShortMonths();
		String[] realMonths = new String[12];
		for (int i = 0; i < 12; i++) {
			realMonths[i] = months[i];
		}
		mMonthPicker.setAdapter(new ArrayWheelAdapter<String>(realMonths));
		mMonthPicker.addChangingListener(new OnWheelChangedListener() {
			@Override
			public void onChanged(WheelView wheel, int oldValue, int newValue) {
				mMonth = newValue;
				adjustMaxDay();
				updateDaySpinner();
				if (mOnDateWheelPickerDateChangedListener != null) {
					mOnDateWheelPickerDateChangedListener.onDateWheelPickerDateChanged(mYear, mMonth, mDay + 1);
				}
			}
		});

		// ////////////////////////////////
		mYearPicker = (WheelView) findViewById(R.id.second);
		mYearPicker.setCyclic(true);
		mYearPicker.addChangingListener(new OnWheelChangedListener() {
			@Override
			public void onChanged(WheelView wheel, int oldValue, int newValue) {
				mYear = newValue + 1900;
				adjustMaxDay();
				updateDaySpinner();
				if (mOnDateWheelPickerDateChangedListener != null) {
					mOnDateWheelPickerDateChangedListener.onDateWheelPickerDateChanged(mYear, mMonth, mDay + 1);
				}
			}
		});
		mYearPicker.setAdapter(new NumericWheelAdapter(DEFAULT_START_YEAR, DEFAULT_END_YEAR));

		// set current time
		Calendar c = Calendar.getInstance();

		int curYears = c.get(Calendar.YEAR);
		int curMonths = c.get(Calendar.MONTH);
		int curDays = c.get(Calendar.DAY_OF_MONTH);

		Log.e("Day", "" + curDays);
		Log.e("Mon", "" + curMonths);
		Log.e("Year", "" + curYears);
		mDay = curDays;
		mMonth = curMonths;
		mYear = curYears;

		mYearPicker.setCurrentItem(curYears - 1900);
		mMonthPicker.setCurrentItem(curMonths);
		mDayPicker.setCurrentItem(curDays - 1);

		// add listeners
		// addChangingListener(mYearPicker, "s");
		// addChangingListener(mMonthPicker, "m");
		// addChangingListener(mDayPicker, "h");

		OnWheelChangedListener wheelListener = new OnWheelChangedListener() {
			public void onChanged(WheelView wheel, int oldValue, int newValue) {
				if (!timeScrolled) {
					timeChanged = true;
					if (mOnDateWheelPickerDateChangedListener != null) {
						mOnDateWheelPickerDateChangedListener.onDateWheelPickerDateChanged(mYear, mMonth, mDay + 1);
					}
					timeChanged = false;
				}
			}
		};

		mDayPicker.addChangingListener(wheelListener);
		mMonthPicker.addChangingListener(wheelListener);
		mYearPicker.addChangingListener(wheelListener);

		OnWheelScrollListener scrollListener = new OnWheelScrollListener() {
			public void onScrollingStarted(WheelView wheel) {
				timeScrolled = true;
			}

			public void onScrollingFinished(WheelView wheel) {
				timeScrolled = false;
				timeChanged = true;
				// picker.setCurrentHour(mDayPicker.getCurrentItem());
				// picker.setCurrentMinute(mMonthPicker.getCurrentItem());
				// picker.updateDate(mYearPicker.getCurrentItem(),
				// mMonthPicker.getCurrentItem(), mDayPicker
				// .getCurrentItem());
				timeChanged = false;
			}
		};

		mDayPicker.addScrollingListener(scrollListener);
		mMonthPicker.addScrollingListener(scrollListener);
		mYearPicker.addScrollingListener(scrollListener);

		button_ok = (Button) findViewById(R.id.confirmbutton);
		button_ok.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mOnDateWheelPickerDateSettedListener != null) {
					mOnDateWheelPickerDateSettedListener.onDateWheelPickerDateSetted(mYear, mMonth, mDay + 1);
				}
			}
		});
		button_cancel = (Button) findViewById(R.id.cancelbutton);
		button_cancel.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mOnDateWheelPickerDateSettedListener != null) {
					mOnDateWheelPickerDateSettedListener.onDateWheelPickerDateSetted(mYear, mMonth, mDay + 1);
				}
			}
		});

	}

	public void setOnDateWheelPickerDateChangedListener(OnDateWheelPickerDateChangedListener onDateWheelPickerDateChangedListener) {
		this.mOnDateWheelPickerDateChangedListener = onDateWheelPickerDateChangedListener;
	}

	public void setOnDateWheelPickerDateSettedListener(OnDateWheelPickerDateSettedListener onDateWheelPickerDateSettedListener) {
		this.mOnDateWheelPickerDateSettedListener = onDateWheelPickerDateSettedListener;
	}

	private void updateDaySpinner() {
		Calendar cal = Calendar.getInstance();
		cal.set(mYear, mMonth + 1, mDay);
		int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		// mDayPicker.setRange(1, max);
		mDayPicker.setAdapter(new NumericWheelAdapter(1, max));
		mDayPicker.setCurrentItem(mDay);
	}

	private void adjustMaxDay() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, mYear);
		cal.set(Calendar.MONTH, mMonth + 1);
		int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		if (mDay > max) {
			mDay = max;
		}
	}

	/**
	 * Adds changing listener for wheel that updates the wheel label
	 * 
	 * @param wheel
	 *            the wheel
	 * @param label
	 *            the wheel label
	 */
	private void addChangingListener(final WheelView wheel, final String label) {
		wheel.addChangingListener(new OnWheelChangedListener() {
			public void onChanged(WheelView wheel, int oldValue, int newValue) {
				// wheel.setLabel(newValue != 1 ? label + "s" : label);
				wheel.setLabel(label);
			}
		});
	}
}
